/* 
 * Pessoa.java
 * 
 * Data de criação: 06/09/2010
 * 
 * O2SOLUTIONS - SOLUÇÕES EM TECNOLOGIA DA INFORMAÇÃO. 
 *
 */
package br.com.o2solutions.siso.integration.entidade;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import br.com.o2solutions.core.integration.repository.entity.BaseEntity;
import br.com.o2solutions.siso.integration.entidade.enumerator.TipoPessoaEnumerator;

/**
 * Classe responsável por representar a abstração de uma pessoa para o sistema.
 * 
 * @author Osvaldeir
 * @since 06/09/2010
 * 
 */
@Table
@Entity(name = "TBPESSOA")
@Inheritance(strategy = InheritanceType.JOINED)
@SequenceGenerator(name = "SQPESSOA", sequenceName = "SQPESSOA")
public class Pessoa extends BaseEntity<Integer> {

	private static final long serialVersionUID = 1L;

	private String nome;

	private String sobreNome;

	private Date dataNascimento;

	private TipoPessoaEnumerator tipoPessoa;

	private Endereco endereco;

	private List<Contato> contatos;

	private Pessoa mae;

	private Pessoa pai;

	@Id
	@Override
	@Column(name = "PESSOAID")
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SQPESSOA")
	public Integer getId() {
		return super.getId();
	}

	/**
	 * Retorna o(a) nome.
	 * 
	 * @return String
	 */
	@Column(name = "NOME", nullable = false, length = 50)
	public String getNome() {
		return nome;
	}

	/**
	 * Atribui o(a) nome.
	 * 
	 * @param nome
	 *            String
	 */
	public void setNome(String nome) {
		this.nome = nome;
	}

	/**
	 * Retorna o(a) sobreNome.
	 * 
	 * @return String
	 */
	@Column(name = "SOBRENOME", nullable = false, length = 150)
	public String getSobreNome() {
		return sobreNome;
	}

	/**
	 * Atribui o(a) sobreNome.
	 * 
	 * @param sobreNome
	 *            String
	 */
	public void setSobreNome(String sobreNome) {
		this.sobreNome = sobreNome;
	}

	/**
	 * Retorna o(a) dataNascimento.
	 * 
	 * @return Date
	 */
	@Temporal(TemporalType.DATE)
	@Column(name = "DATANASCIMENTO", nullable = false)
	public Date getDataNascimento() {
		return dataNascimento;
	}

	/**
	 * Atribui o(a) dataNascimento.
	 * 
	 * @param dataNascimento
	 *            Date
	 */
	public void setDataNascimento(Date dataNascimento) {
		this.dataNascimento = dataNascimento;
	}

	/**
	 * Retorna o(a) tipoPessoa.
	 * 
	 * @return TipoPessoa
	 */
	@Enumerated(EnumType.STRING)
	@Column(name = "TIPOPESSOA", nullable = false)
	public TipoPessoaEnumerator getTipoPessoa() {
		return tipoPessoa;
	}

	/**
	 * Atribui o(a) tipoPessoa.
	 * 
	 * @param tipoPessoa
	 *            TipoPessoa
	 */
	public void setTipoPessoa(TipoPessoaEnumerator tipoPessoa) {
		this.tipoPessoa = tipoPessoa;
	}

	/**
	 * Retorna o(a) endereco.
	 * 
	 * @return Endereco
	 */
	@ManyToOne(cascade = {CascadeType.ALL})
	@JoinColumn(name = "ENDERECOID", nullable = true)
	public Endereco getEndereco() {
		return endereco;
	}

	/**
	 * Atribui o(a) endereco.
	 * 
	 * @param endereco
	 *            Endereco
	 */
	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}

	/**
	 * Retorna o(a) mae.
	 * 
	 * @return Pessoa
	 */
	@ManyToOne
	@JoinColumn(name = "MAEID", nullable = true)
	public Pessoa getMae() {
		return mae;
	}

	/**
	 * Atribui o(a) mae.
	 * 
	 * @param mae
	 *            Pessoa
	 */
	public void setMae(Pessoa mae) {
		this.mae = mae;
	}

	/**
	 * Retorna o(a) pai.
	 * 
	 * @return Pessoa
	 */
	@ManyToOne
	@JoinColumn(name = "PAIID", nullable = true)
	public Pessoa getPai() {
		return pai;
	}

	/**
	 * Atribui o(a) pai.
	 * 
	 * @param pai
	 *            Pessoa
	 */
	public void setPai(Pessoa pai) {
		this.pai = pai;
	}

	/**
	 * Retorna o(a) contatos.
	 * 
	 * @return List<Contato>
	 */
	@ManyToMany
	@JoinTable(name = "RLPESSOACONTATO", joinColumns = { @JoinColumn(name = "PESSOAID") }, inverseJoinColumns = { @JoinColumn(name = "CONTATOID") })
	public List<Contato> getContatos() {
		if (contatos == null) {
			contatos = new ArrayList<Contato>();
		}
		return contatos;
	}

	/**
	 * Atribui o(a) contatos.
	 * 
	 * @param contatos
	 *            List<Contato>
	 */
	public void setContatos(List<Contato> contatos) {
		this.contatos = contatos;
	}

	/**
	 * Adiciona um novo {@link Contato} a lista de Contatos da Pessoa desde que
	 * não seja nulo.
	 * 
	 * @param contato
	 *            Contato a ser adicionado.
	 */
	public void adicionarContato(Contato contato) {
		if (contato != null) {
			getContatos().add(contato);
		}
	}

}
